package com.qf.ability.gateway.security.authmanager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * 自定义的身份认证管理器 - 进行身份认证的过程
 */
@Component
public class ClustemAutnenticationManager implements ReactiveAuthenticationManager {

    @Autowired
    private TokenStore tokenStore;

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
//        System.out.println("自定义身份认证管理器是否触发！！！！！！！" + authentication);
//        if (authentication instanceof BearerTokenAuthenticationToken) {
//            //Authentication的类型转换
//            BearerTokenAuthenticationToken bearerTokenAuthenticationToken = (BearerTokenAuthenticationToken) authentication;
//            //获取当前的请求令牌
//            String token = bearerTokenAuthenticationToken.getToken();
//
//            OAuth2AccessToken oAuth2AccessToken = null;
//            try {
//                //解析令牌的内容
//                oAuth2AccessToken = tokenStore.readAccessToken(token);
//            } catch (Exception e) {
//                throw new InvalidBearerTokenException("令牌格式不正确");
//            }
//
//            //判断令牌是否过期
//            if (oAuth2AccessToken.isExpired()) {
//                throw new InvalidBearerTokenException("令牌已经过期");
//            }
//
//            //解析令牌的有效性并且转换成Oauth2的Authentication对象
//            OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(oAuth2AccessToken);
//            System.out.println("转换后的Authentication：" + oAuth2Authentication);
//            return Mono.just(oAuth2Authentication);
//        }

        return Mono.just(authentication)
                .filter(auth -> auth instanceof BearerTokenAuthenticationToken) //if (authentication instanceof BearerTokenAuthenticationToken)
                .cast(BearerTokenAuthenticationToken.class) //BearerTokenAuthenticationToken bearerTokenAuthenticationToken = (BearerTokenAuthenticationToken) authentication;
                .map(bearerTokenAuthenticationToken -> bearerTokenAuthenticationToken.getToken())//String token = bearerTokenAuthenticationToken.getToken();
                .map(token -> tokenStore.readAccessToken(token))//oAuth2AccessToken = tokenStore.readAccessToken(token);
                .onErrorMap(throwable -> new InvalidBearerTokenException("令牌格式不正确"))
                .filter(oAuth2AccessToken -> !oAuth2AccessToken.isExpired())
                .switchIfEmpty(Mono.error(new InvalidBearerTokenException("令牌已经过期")))
                .flatMap(oAuth2AccessToken -> {
                    OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(oAuth2AccessToken);
                    return Mono.just(oAuth2Authentication);
                });
    }
}
